/**
 * com.dingjian.permission.interceptor.PermissionInterceptor.java
 */
package com.dingjian.permission.interceptor;

import java.lang.reflect.Method;
import java.util.Set;

import javax.naming.NoPermissionException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.dingjian.base.spring.ApplicationContextAware;
import com.dingjian.permission.controller.PermissionItemListController;

/**
 * 权限拦截器
 * 以web请求为入口，采用方法拦截的方式
 * @author FengMy
 * 
 * @since 2012-9-20
 */
@SuppressWarnings("unchecked")
public class PermissionInterceptor extends HandlerInterceptorAdapter {
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		HandlerMethod hm = (HandlerMethod) handler;
		Class<?> beanClass = hm.getBean().getClass();
		Method method = hm.getMethod();
		String className =  beanClass.getName();
		String methodName = method.getName();
		String permissionMethodName = className + "." + methodName;
		HttpSession session = request.getSession();
		Set<String> wholePermissionMethod = getPermissionMethods(session.getServletContext());
		if(wholePermissionMethod != null && wholePermissionMethod.contains(permissionMethodName)){
			//存在权限控制
			Set<String> personPermissions = (Set<String>) session.getAttribute("PERSONAL-PERMISSION");
			if(personPermissions != null && !personPermissions.contains(permissionMethodName)){
				throw new NoPermissionException("NO-PERMISSION");
			}
		}
		return super.preHandle(request, response, handler);
	}
	
	private Set<String> getPermissionMethods(ServletContext context){
		Set<String> permissionMethods = (Set<String>) context.getAttribute("WHOLE-PERMISSIONMETHODS");
		if(permissionMethods==null){
			PermissionItemListController c = ApplicationContextAware.getApplicationContext().getBean(PermissionItemListController.class);
			c.loadPermissions();
			permissionMethods = (Set<String>) context.getAttribute("WHOLE-PERMISSIONMETHODS");
		}
		return permissionMethods;
	}
}
